package LoginServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.Vector;

public class Login_Socket {
	private ServerSocket servSocket;
	public static Vector<Resource> res = new Vector();
	
	
		
	public void openSocket(int port){
		
		// Setting Socket
		System.out.println("Trying to open the PORT : " + port);
		try	{
			servSocket = new ServerSocket(port);  
		}catch(IOException e){
		   System.out.println("Can't open the PORT");
		   System.exit(1);
		}
		do{
			Socket client;
			try {
				client = servSocket.accept();
				System.out.println("*New Client have been arrived*");
				ClientHandler handler = new ClientHandler(client);
				// Connect Client by using Thread 
				handler.start();
			} catch (IOException e) {
				System.out.println("Can't accept the Client");
			}
		}while (true);
	}
}

class ClientHandler extends Thread{
	private Socket client;
	private BufferedReader in;
	private PrintWriter out;
	
	private ObjectOutputStream oout;
	private ObjectInputStream oin;
	
	
	public ClientHandler(Socket socket)	{
		client = socket;
		try	{
			in = new BufferedReader(new InputStreamReader(client.getInputStream()));
			out = new PrintWriter(client.getOutputStream(),true);
			
			oin = new ObjectInputStream(client.getInputStream());
			oout = new ObjectOutputStream(client.getOutputStream());
			
			
		}catch(IOException e)	{
			e.printStackTrace();
		}
		//out.println("Multi_thread_server have been started");
	}
	

	private boolean runable = true; 
	public void run(){
		
		try	{
			
			//연결이 종료될 때 까지 돌린다.
			do{
				
				messageParse();
				
			}while (runable);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			
			//연결 종료
			try	{
				if (client != null){
					System.out.println("\tDisconnect from the client");
					client.close();
				}
			}
			catch(IOException e){
				e.printStackTrace();
			}
		}
	}

	
	
	private String[] split(String str){
		return str.split("\\|");
	}

	private void messageParse(){
		
		String message = null;
		
		try {
			message = in.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// Classify Message
		if (message != null){			
			
			//구분자 | 로 메시지를 쪼개어 나눈다
			//자바에서는 |를 바로 쓰지 못하고 \\|로 사용할 수 있다.
			
			if (message.startsWith("VIEW")){
				
				//VIEW명령어에서는
				//VIEW|방이름
				//리턴값은 IP
				//해당 방이 없으면 리턴값은 :ANS
				
				String[] splitString =  split(message);
				if (splitString.length == 2){
					//정확히 2칸이면
					String ip = null;
					Iterator<Resource> i =  Login_Socket.res.iterator();
					
					//검색해서 해당 방이 있으면 아이피를 찾는다.
					while(i.hasNext()){
						Resource res = i.next();
						if (res.getRoom().equals(splitString[1])){
							ip = res.getIp();
						}
					}
					
					//리턴
					if (ip != null){
						out.println(ip);
					}else{
						out.println(":ANS");
					}
				}	
			}else if (message.startsWith("MAKE")){
				
				//MAKE명령어에서는
				//MAKE|방이름|아이피
				//3칸으로 구성
				//리턴값은 :ANS
				
				String[] splitString =  split(message);
				if (splitString.length == 3){
					//정확히 3칸이면 리소스 백터에 집어 넣는다.
					Resource res = new Resource();
					res.setIp(splitString[2]);
					res.setRoom(splitString[1]);
					Login_Socket.res.add(res);
				}				
				
				out.println(":ANS");
			}else if (message.startsWith("LIST")){
				
				//리소스를 목록을 만들어 보낸다.
				Iterator<Resource> i =  Login_Socket.res.iterator();
				String ret = "";
				while(i.hasNext()){
					//구분자는 |
					Resource res = i.next();
					
					ret += res.getRoom();
					
					if(i.hasNext())
						ret += "|";
				}
				
				if (ret.equals("")){
					ret = ":ANS";
				}
				out.println(ret);
			}else{
				//해석하지 못하는 명령어
				out.println(":ANS");
			}
			System.out.println("\t[" + client.getInetAddress().getHostAddress() + "] : "+message.trim());
		}else{
			System.out.println("\t[" + client.getInetAddress().getHostAddress() + "] : closed");
			runable = false;
		}
		
		
	}
}
class Resource {
	private String ip;
	private String room;
	 
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}
	public String getRoom() {
		return room;
	}
	public void setRoom(String room) {
		this.room = room;
	}
}
